﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Bmz.Laboratory.DesignPattern
{
    /// <summary>
    /// 桥接模式
    /// http://www.cnblogs.com/houleixx/archive/2008/02/23/1078877.html
    /// 
    /// http://www.cnblogs.com/zhili/p/BridgePattern.html
    /// </summary>
    public class Bridge
    {
        #region 电视和遥控器案例
        /// <summary>
        /// 抽象概念中的遥控器，扮演抽象化角色
        /// </summary>
        public class RemoteControl
        {
            // 字段
            private TV implementor;

            // 属性
            public TV Implementor
            {
                get { return implementor; }
                set { implementor = value; }
            }

            /// <summary>
            /// 开电视机，这里抽象类中不再提供实现了，而是调用实现类中的实现
            /// </summary>
            public virtual void On()
            {
                implementor.On();
            }

            /// <summary>
            /// 关电视机
            /// </summary>
            public virtual void Off()
            {
                implementor.Off();
            }

            /// <summary>
            /// 换频道
            /// </summary>
            public virtual void SetChannel()
            {
                implementor.tuneChannel();
            }
        }

        /// <summary>
        /// 具体遥控器
        /// </summary>
        public class ConcreteRemote : RemoteControl
        {
            public override void SetChannel()
            {
                Console.WriteLine("---------------------");
                base.SetChannel();
                Console.WriteLine("---------------------");
            }
        }

        /// <summary>
        /// 电视机，提供抽象方法
        /// </summary>
        public abstract class TV
        {
            public abstract void On();
            public abstract void Off();
            public abstract void tuneChannel();
        }

        /// <summary>
        /// 长虹牌电视机，重写基类的抽象方法
        /// 提供具体的实现
        /// </summary>
        public class ChangHong : TV
        {
            public override void On()
            {
                Console.WriteLine("长虹牌电视机已经打开了");
            }

            public override void Off()
            {
                Console.WriteLine("长虹牌电视机已经关掉了");
            }

            public override void tuneChannel()
            {
                Console.WriteLine("长虹牌电视机换频道");
            }
        }

        /// <summary>
        /// 三星牌电视机，重写基类的抽象方法
        /// </summary>
        public class Samsung : TV
        {
            public override void On()
            {
                Console.WriteLine("三星牌电视机已经打开了");
            }

            public override void Off()
            {
                Console.WriteLine("三星牌电视机已经关掉了");
            }

            public override void tuneChannel()
            {
                Console.WriteLine("三星牌电视机换频道");
            }
        }

        /// <summary>
        /// 以电视机遥控器的例子来演示桥接模式
        /// </summary>
        class Client
        {
            static void main(string[] args)
            {
                // 创建一个遥控器
                RemoteControl remoteControl = new ConcreteRemote();
                // 长虹电视机
                remoteControl.Implementor = new ChangHong();
                remoteControl.On();
                remoteControl.SetChannel();
                remoteControl.Off();
                Console.WriteLine();

                // 三星牌电视机
                remoteControl.Implementor = new Samsung();
                remoteControl.On();
                remoteControl.SetChannel();
                remoteControl.Off();
                Console.Read();
            }
        }
        #endregion

        #region 人，车和路的按钮
        
        //抽象路
        public abstract class AbstractRoad
        {
            protected AbstractCar car;
            public AbstractCar Car
            {
                set
                {
                    car = value;
                }
            }

            public abstract void Run();
        }
        //高速公路
        public class SpeedWay : AbstractRoad
        {
            public override void Run()
            {
                car.Run();
                Console.WriteLine("高速公路上行驶");
            }
        }

        //市区街道
        public class Street : AbstractRoad
        {
            public override void Run()
            {
                car.Run();
                Console.WriteLine("市区街道上行驶");
            }
        }

        //抽象汽车 
        public abstract class AbstractCar
        {
            public abstract void Run();
        }

        //小汽车;
        public class Car : AbstractCar
        {
            public override void Run()
            {
                Console.WriteLine("小汽车");
            }
        }

        //公共汽车
        public class Bus : AbstractCar
        {
            public override void Run()
            {
                Console.WriteLine("公共汽车");
            }
        }

        abstract class people
        {
            AbstractRoad road;
            public AbstractRoad Road
            {
                get
                {
                    return road;
                }
                set
                {
                    road = value;
                }
            }
            public abstract void Run();

        }
        class Man : people
        {
            public override void Run()
            {
                Console.Write("男人开着");
                Road.Run();
            }
        }

        class WoMan : people
        {
            public override void Run()
            {
                Console.Write("女人开着");
                Road.Run();
            }
        }

        //  public static void Main(string[] args)
        //{
        //    //小汽车在高速公路上行驶;
        //    AbstractRoad Road1 = new SpeedWay();
        //    Road1.Car = new Car();
        //    Road1.Run();
        //    Console.WriteLine("=========================");
        //    //公共汽车在高速公路上行驶;
        //    AbstractRoad Road2 = new SpeedWay();
        //    Road2.Car = new Bus();
        //    Road2.Run();
        //    Console.Read();
        //}

        static void main(string[] args)
        {

            //男人开着公共汽车在高速公路上行驶;
            Console.WriteLine("=========================");

            AbstractRoad Road3 = new SpeedWay();
            Road3.Car = new Bus();

            people p = new Man();
            p.Road = Road3;
            p.Run();

            Console.Read();
        }
        #endregion
    }
}
